<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>AngelScript: Timeout long running scripts</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>


</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">AngelScript
   
   </div>
   
  </td>
  
  
  
   
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.5.1 -->
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
  initNavTree('doc_adv_timeout.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Timeout long running scripts </div>  </div>
</div>
<div class="contents">
<div class="textblock"><p>To prevent long running scripts to freeze the application it may be necessary to add a way to timeout the execution. This article presents two different ways to do so.</p>
<h2><a class="anchor" id="doc_adv_timeout_1"></a>
With the line callback</h2>
<p>The line callback feature can be used to perform some special treatment during execution of the scripts. The callback is called for every script statement, which for example makes it possible to verify if the script has executed for too long time and if so suspend the execution to be resumed at a later time.</p>
<p>Before calling the context's <a class="el" href="classas_i_script_context.html#a8e52894432737acac2e1a422e496bf84">Execute</a> method, set the callback function like so:</p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> ExecuteScriptWithTimeOut(<a class="code" href="classas_i_script_context.html" title="The interface to the virtual machine.">asIScriptContext</a> *ctx)
{
  <span class="comment">// Define the timeout as 1 second</span>
  DWORD timeOut = timeGetTime() + 1000;

  <span class="comment">// Set up the line callback that will timout the script</span>
  ctx-&gt;<a class="code" href="classas_i_script_context.html#ae2747f643bf9a07364f922c460ef57dd" title="Sets a line callback function. The function will be called for each executed script statement...">SetLineCallback</a>(<a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(LineCallback), &amp;timeOut, <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>);

  <span class="comment">// Execute the script</span>
  <span class="keywordtype">int</span> status = ctx-&gt;<a class="code" href="classas_i_script_context.html#a8e52894432737acac2e1a422e496bf84" title="Executes the prepared function.">Execute</a>();

  <span class="comment">// If the status is asEXECUTION_SUSPENDED the script can</span>
  <span class="comment">// be resumed by calling this function again.</span>
  <span class="keywordflow">return</span> status;
}

<span class="comment">// The line callback function is called by the VM for each statement that is executed</span>
<span class="keywordtype">void</span> LineCallback(<a class="code" href="classas_i_script_context.html" title="The interface to the virtual machine.">asIScriptContext</a> *ctx, DWORD *timeOut)
{
  <span class="comment">// If the time out is reached we suspend the script</span>
  <span class="keywordflow">if</span>( *timeOut &lt; timeGetTime() )
    ctx-&gt;<a class="code" href="classas_i_script_context.html#ad4ac8be3586c46069b5870e40c86544a" title="Suspends the execution, which can then be resumed by calling Execute again.">Suspend</a>();
}
</pre></div><p>Take a look at the sample <a class="el" href="doc_samples_events.html">Events</a> to see this working.</p>
<h2><a class="anchor" id="doc_adv_timeout_2"></a>
With a secondary thread</h2>
<p>A second thread can be set up to suspend the execution after the timeout. This thread can then be put to sleep so that it doesn't impact performance during the execution. When the thread wakes up it should call the context's <a class="el" href="classas_i_script_context.html#ad4ac8be3586c46069b5870e40c86544a">Suspend</a> method.</p>
<p>The below shows some possible code for doing this. Note that the code for setting up the thread is fictive, as this is different for each target OS.</p>
<div class="fragment"><pre class="fragment"><span class="comment">// The variables that are shared between the threads</span>
<a class="code" href="classas_i_script_context.html" title="The interface to the virtual machine.">asIScriptContext</a> *threadCtx;
<span class="keywordtype">int</span> threadId;

<span class="comment">// This function will be executed in the secondary thread</span>
<span class="keywordtype">void</span> SuspendThread()
{
  <span class="comment">// Put the thread to sleep until the timeout (1 second)</span>
  Sleep(1000);
  
  <span class="comment">// When we wake-up we call the context&#39;s Suspend method</span>
  ctx-&gt;<a class="code" href="classas_i_script_context.html#ad4ac8be3586c46069b5870e40c86544a" title="Suspends the execution, which can then be resumed by calling Execute again.">Suspend</a>();
}

<span class="comment">// This function sets up the timeout thread and executes the script</span>
<span class="keywordtype">int</span> ExecuteScriptWithTimeOut(<a class="code" href="classas_i_script_context.html" title="The interface to the virtual machine.">asIScriptContext</a> *ctx)
{
  <span class="comment">// Set the shared context pointer before creating the thread</span>
  threadCtx = ctx;

  <span class="comment">// Create the thread that will immediately go to sleep</span>
  threadId = CreateThread(SuspendThread);
  
  <span class="comment">// Execute the script</span>
  <span class="keywordtype">int</span> status = ctx-&gt;<a class="code" href="classas_i_script_context.html#a8e52894432737acac2e1a422e496bf84" title="Executes the prepared function.">Execute</a>();
  
  <span class="comment">// Destroy the secondary thread before releasing the context</span>
  DestroyThread(threadId);
  
  <span class="comment">// Clear the global variables</span>
  threadId = 0;
  threadCtx = 0;
  
  <span class="comment">// If the status is asEXECUTION_SUSPENDED the script can</span>
  <span class="comment">// be resumed by calling this function again.</span>
  
  <span class="keywordflow">return</span> status;
}
</pre></div><p>Observe that this way of doing it is safe even if the AngelScript library has been built without <a class="el" href="doc_adv_multithread.html">multithread support</a>. </p>
</div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>

    <li class="footer">Generated on Sun Jan 29 2012 15:41:03 for AngelScript by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.5.1 </li>
   </ul>
 </div>


</body>
</html>
